package ext.tianma.part;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import wt.change2.WTChangeOrder2;
import wt.enterprise.RevisionControlled;
import wt.fc.Persistable;
import wt.fc.PersistenceHelper;
import wt.fc.QueryResult;
import wt.part.WTPart;
import wt.part.WTPartConfigSpec;
import wt.part.WTPartHelper;
import wt.part.WTPartMaster;
import wt.part.WTPartStandardConfigSpec;
import wt.part.WTPartUsageLink;
import wt.query.QuerySpec;
import wt.query.SearchCondition;
import wt.util.WTException;
import wt.util.WTPropertyVetoException;
import wt.vc.VersionControlHelper;
import wt.vc.config.ConfigException;
import wt.vc.config.ConfigSpec;
import wt.vc.config.LatestConfigSpec;
import wt.vc.struct.StructHelper;
import wt.vc.views.View;
import wt.vc.views.ViewHelper;
import wt.vc.views.ViewReference;
import ext.com.core.CoreUtil;
import ext.tianma.part.forms.TMTypeUtil;

public class MyPartUtil {
	
	public static QueryResult getWTChangeRequest2( WTChangeOrder2 ecn ){
		
		QueryResult qr = null;
		
		if( ecn != null ){
			
			
			
		}
		
		return qr;
		
	}
	
	/**
	 * 根据零部件编号，视图和版本获取零部件对象
	 * 
	 * @param number
	 * @param view
	 * @param version
	 * @return
	 * @throws WTException
	 */
	public static WTPart getWTPartByNumViewAndVersion(String number , String view , String version) throws WTException {
		WTPart part = null ;
		QuerySpec qs = new QuerySpec(WTPartMaster.class);
		
		//定义搜索条件，以零部件编号方式在master中搜索
		SearchCondition sc = new SearchCondition(WTPartMaster.class, WTPartMaster.NUMBER, SearchCondition.EQUAL, number );
		qs.appendSearchCondition(sc);
		
		QueryResult qr = PersistenceHelper.manager.find(qs);
		while (qr.hasMoreElements()) {
			WTPartMaster master = (WTPartMaster) qr.nextElement();
			if( master != null ){
				part = getWTPartByNumViewAndVersion( master , view , version) ;
			}
		}

		return part ;
	}
	
	/**
	 * 根据编号获取Master
	 * @param number
	 * @return
	 * @throws WTException
	 */
	public static WTPartMaster getWTPartMasterByNumber( String number ) throws WTException{
		WTPartMaster partMaster = null;
		
		if( number != null && !number.equals("") ){
			QuerySpec qs = new QuerySpec(WTPartMaster.class);
			SearchCondition sc = new SearchCondition(WTPartMaster.class, WTPartMaster.NUMBER, SearchCondition.EQUAL, number );
			qs.appendSearchCondition(sc);
			
			QueryResult qr = PersistenceHelper.manager.find(qs);
			if( qr != null && qr.size()>0 ){
				partMaster = (WTPartMaster) qr.nextElement();
			}
			
		}
		return partMaster;
	}
	
	/**
	 * 根据零部件主数据(master)和视图获取对应最新版本零部件
	 * @author Harry Cao
	 * @param master
	 * @param view
	 * @return
	 * @throws WTException
	 */
	public static WTPart getWTPartByNumViewAndVersion(WTPartMaster master , String view , String version) throws WTException {
		WTPart part = null;
		//根据视图名称获取视图对象
		View viewObj = ViewHelper.service.getView(view);

		//根据视图构造产品结构配置规范
		WTPartStandardConfigSpec standardConfig = WTPartStandardConfigSpec.newWTPartStandardConfigSpec(viewObj, null);
		try {
			standardConfig.setView(viewObj);
		} catch (WTPropertyVetoException wpve) {
			throw new WTException(wpve);
		}

		//根据master和视图获取对应最新的视图版本零部件
		//QueryResult qr = ConfigHelper.service.filteredIterationsOf(master, standardConfig);
		
		//获取所有版本的零部件
		QueryResult qr=VersionControlHelper.service.allIterationsOf(master);
		//System.out.println(">>>>> 根据编号和视图获取到的零部件对象数量为：" + qr.size()) ;
		
		while ( qr.hasMoreElements() ) {
			part = (WTPart) qr.nextElement();
			
			String partVersion = getVersion( part ) ;
			if(version.equals( partVersion ) && part.getViewName().equals(view)){
				return part ;
			}
		}
		
		
		return null ;
	}
	
	/**
	 * 获取对象的大小版本组成的版本序列值，形如： A.1
	 * 
	 * @param revisionControlled
	 * @return
	 */
	public static String getVersion(RevisionControlled revisionControlled){

		String version = "";
		
		if( revisionControlled != null ){
			//获取大版本
			String majorVersion = revisionControlled.getVersionIdentifier().getValue();
			
			
			// 获取小版本
			String minorVersion = revisionControlled.getIterationIdentifier().getValue();

			version = majorVersion;
		}
		
		return version;
	}
	
	/**
	 * 获取零部件BOM结构下的所有的使用关系
	 * 
	 * @param part
	 * @return
	 * @throws ConfigException
	 * @throws WTException
	 */
	public static List<WTPartUsageLink> getAllLevelUsageLink(WTPart part) throws ConfigException, WTException {
		List<WTPartUsageLink> allPartUsageLinkList = new ArrayList<WTPartUsageLink>() ;
		
		if( part == null ){
			return allPartUsageLinkList ; 
		}
		
		String viewName = part.getViewName() ;
		
		//方法返回的List，用于收集整个结构中所有的WTPartUsageLink
		allPartUsageLinkList = getFirstLevelUsageLink( part ) ;
		
		//临时变量，用于实现递归算法
		List<WTPartUsageLink> tempUsageLinkList = allPartUsageLinkList ;

		//临时变量，用于收集每一层零部件的所有WTPartUsageLink，并最后赋值给tempUsageLinkList，实现递归
		List<WTPartUsageLink> tempList = new ArrayList<WTPartUsageLink>() ;
		
		while( tempUsageLinkList.size() > 0 ){
			//每次递归开始时，清空临时存储列表，重新收集当前层下的所有WTPartUsageLink
			tempList.clear() ;
			
			Iterator<WTPartUsageLink> usageLinkIte = tempUsageLinkList.iterator() ;
			while( usageLinkIte.hasNext() ){
				WTPartUsageLink usageLink = usageLinkIte.next() ;
				
				WTPartMaster childMaster = usageLink.getUses() ;
				WTPart childPart = CoreUtil.getWTPartByMasterAndView( childMaster , viewName ) ;
				
				if( childPart != null ){
					tempList.addAll( getFirstLevelUsageLink( childPart ) ) ;
				}
			}
			
			tempUsageLinkList = tempList ;
			
			allPartUsageLinkList.addAll( tempUsageLinkList ) ;
		}
		
		return allPartUsageLinkList ;
	}
	
	/**
	 * 获取零部件第一层父子件使用关系
	 * 
	 * @param part
	 * @return
	 * @throws ConfigException
	 * @throws WTException
	 */
	public static List<WTPartUsageLink> getFirstLevelUsageLink(WTPart part) throws ConfigException, WTException {
		List<WTPartUsageLink> subPartUsageLinkList = new ArrayList<WTPartUsageLink>() ;
		
		ConfigSpec latestconfigspec = getConfigSpec(part);
		
		QueryResult qr= StructHelper.service.navigateUsesToIteration(part,WTPartUsageLink.class,false,latestconfigspec);
		
		while(qr != null && qr.hasMoreElements()){
			//每一个element实际是一个persistable数组
			Persistable apersistable[] = ( Persistable[] ) qr.nextElement();  
			
			//数组中第一个对象是usagelink
			WTPartUsageLink partUsageLink= (WTPartUsageLink)apersistable[0];   
			
			if(partUsageLink != null){
				subPartUsageLinkList.add(partUsageLink) ;
			}
		}
		
		return subPartUsageLinkList;
	}
	
	
	/**
	 * 获取零部件第一层子件
	 * 
	 * @param part
	 * @return
	 * @throws ConfigException
	 * @throws WTException
	 */
	public static List<WTPart> getFirstLevelChildren(WTPart part) throws ConfigException, WTException {
//		boolean flag = SessionServerHelper.manager.setAccessEnforced(false);
		
		List<WTPart> subPartList = new ArrayList<WTPart>() ;
		
		try{
			ConfigSpec latestconfigspec = getConfigSpec(part);
			
			QueryResult qr= StructHelper.service.navigateUsesToIteration(part,WTPartUsageLink.class,false,latestconfigspec);
			
			while(qr != null && qr.hasMoreElements()){
				//每一个element实际是一个persistable数组
				Persistable apersistable[] = ( Persistable[] ) qr.nextElement();  
				
				//数组中第一个对象是usagelink			
				//数组中第二个对象是子件
				//如果当前用户的权限正常，应该是个WTPart
				//反之返回的是WTPartMaster
				//一般是前一种情况居多，这样可以省掉查询子件最新版本的代码，这样代码的执行效率大大增加
				Object uses= apersistable[1];   
				
				WTPart subPart=null; 
				if( uses instanceof WTPart ){
//					System.out.println("uses instanceof WTPart") ;
					subPart=(WTPart)uses; 
				} else if( uses instanceof WTPartMaster ){
//					System.out.println("uses instanceof WTPartMaster") ;
					WTPartMaster master = (WTPartMaster) uses ;
					subPart = CoreUtil.getWTPartByMasterAndView(master, part.getViewName()) ;
				} else {
//					if( uses != null ){
//						System.out.println("Object uses Type is " + uses.getClass()) ;
//					}else{
//						System.out.println("Object uses == null !") ;
//					}
				}
				
				if( subPart != null ){
					subPartList.add(subPart) ;
				}
			}
		}finally{
//			SessionServerHelper.manager.setAccessEnforced(flag);
		}
		
		return subPartList;
	}
	
	/**
	 * 
	 * @param part
	 * @return
	 */
	private static ConfigSpec getConfigSpec(WTPart part) {
		ConfigSpec latestconfigspec = new LatestConfigSpec();
		
		String view = "";
		ViewReference viewRef =part.getView();
		if(viewRef != null){
			view = viewRef.getName();
		}
		try{
			if(view != null && view.length()>0){
				View viewObj= ViewHelper.service.getView(view);
				WTPartConfigSpec config = WTPartHelper.service.findWTPartConfigSpec();
				WTPartStandardConfigSpec standardConfig= config.getStandard();
				
				standardConfig.setView(viewObj);		
				latestconfigspec = standardConfig;
			}
		}catch(Exception e){
			e.printStackTrace();
		}
		
		return latestconfigspec ;
	}
	
	/**
	 * 获取对象中的所有的UsageLink
	 * @param part
	 * @return
	 */
	public static List< WTPartUsageLink > getAllUsageLink( WTPart part  ){
		
		List< WTPartUsageLink > list = new ArrayList<WTPartUsageLink>();
		
		if( part == null ){
			return list;
		}
		
		String view = part.getViewName();
		
		getAllUsageLink( part , view , list );
		
		return list;		
	}
	
	/**
	 * 获取对象中的所有符合条件的UsageLink
	 * @param part
	 * @param view
	 * @param list
	 * @return
	 */
	private static List< WTPartUsageLink > getAllUsageLink( WTPart part , String view , List< WTPartUsageLink > list){
		
		if( part == null ){
			return list;
		}
		
		try {
			List< WTPartUsageLink > firstLevelUsageLink = getFirstLevelUsageLink( part );
			
			if( firstLevelUsageLink != null && firstLevelUsageLink.size() > 0 ){
				Iterator< WTPartUsageLink > iterator = firstLevelUsageLink.iterator();
				
				while( iterator.hasNext() ){
					WTPartUsageLink usageLink = iterator.next();
					
					if( usageLink != null ){

						WTPartMaster partMaster = usageLink.getUses();
						
						if( partMaster != null ){
							WTPart dPart = CoreUtil.getWTPartByMasterAndView( partMaster , view );
							
							if(!TMTypeUtil.isTwoLevelMaterial(dPart) && !TMTypeUtil.isBLU(dPart)&& !TMTypeUtil.isFPC_PCB(dPart)){
								list.add( usageLink );
								getAllUsageLink( dPart , view , list );
							}
							
						}
					}
				}
			}		
		} catch (ConfigException e) {
			e.printStackTrace();
		} catch (WTException e) {
			e.printStackTrace();
		}
		return list;
		
	}
	
}
